package com.zyg.demo.control;

import android.graphics.Canvas;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.helper.ItemTouchHelper;
import android.view.View;

import com.chad.library.adapter.base.callback.ItemDragAndSwipeCallback;
import com.zyg.demo.adapter.PluginAdapter;
import com.zyg.demo.listener.DragListener;

import java.util.List;

/**
 * 主要逻辑回调类
 *
 * @author zhengyunguang
 * created at 2019-07-8 15:33
 */
public class SelfDragAndSwipeCallback extends ItemDragAndSwipeCallback {

    public static final String PRE_FIX = "SelfDragAndSwipeCallback-->";

    private static final int CHECK_FOLDER_DIS_THREASHOLD = 10000;

    private DragListener dragListener;

    private PluginAdapter mAdapter;

    public void setDragListener(DragListener dragListener) {
        this.dragListener = dragListener;
    }

    public SelfDragAndSwipeCallback(PluginAdapter adapter) {
        super(adapter);
        this.mAdapter = adapter;
    }


    /**
     * 针对swipe和drag状态，当swipe或者drag对应的ViewHolder改变的时候调用
     * 我们可以通过重写这个函数获取到swipe、drag开始和结束时机，viewHolder 不为空的时候是开始，空的时候是结束
     */
    @Override
    public void onSelectedChanged(RecyclerView.ViewHolder viewHolder, int actionState) {
        super.onSelectedChanged(viewHolder, actionState);
        if (actionState == ItemTouchHelper.ACTION_STATE_IDLE) {
            if (dragListener != null) {
                dragListener.onDragRelease();
            }
        }
    }


    /**
     * 针对drag状态,当item长按的时候是否允许进入drag(拖动)状态
     */
    @Override
    public boolean isLongPressDragEnabled() {
        return super.isLongPressDragEnabled();
    }

    /**
     * 针对drag状态，当前target对应的item是否允许move
     * 换句话说我们一般用drag来做一些换位置的操作，就是当前target对应的item是否可以换位置
     */
    public boolean canDropOver(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
        return super.canDropOver(recyclerView, source, target);
    }


    private int getDistance(View current, View target) {
        int margin = this.getBoundingBoxMargin();
        int left = Math.round(current.getLeft() + current.getTranslationX()) - margin;
        int top = Math.round(current.getTop() + current.getTranslationY()) - margin;
        int right = left + current.getWidth() + 2 * margin;
        int bottom = top + current.getHeight() + 2 * margin;
        int centerX = (left + right) / 2;
        int centerY = (top + bottom) / 2;
        int dx = Math.abs(centerX - (target.getLeft() + target.getRight()) / 2);
        int dy = Math.abs(centerY - (target.getTop() + target.getBottom()) / 2);
        return dx * dx + dy * dy;
    }


    /**
     * 针对drag状态，当drag itemView和底下的itemView重叠的时候,可以给drag itemView设置额外的margin，让重叠更加容易发生。
     * 相当于增大了drag itemView的区域
     */
    public int getBoundingBoxMargin() {
        return super.getBoundingBoxMargin();
    }


    /**
     * 针对drag状态，滑动超过百分之多少的距离可以可以调用onMove
     */
    public float getMoveThreshold(RecyclerView.ViewHolder viewHolder) {
        return super.getMoveThreshold(viewHolder);
    }


    private boolean canMove;

    /**
     * dropTargets为移动过程中，所有有交集的item
     * 从中找到距离最近的
     */
    public RecyclerView.ViewHolder chooseDropTarget(RecyclerView.ViewHolder source,
                                                    List<RecyclerView.ViewHolder> dropTargets,
                                                    int curX,
                                                    int curY) {
        if (dragListener != null && dragListener.canSearchFolder(source)) {
            RecyclerView.ViewHolder target = null;
            if (dropTargets != null) {
                for (RecyclerView.ViewHolder holder : dropTargets) {
                    if (getDistance(source.itemView, holder.itemView) < CHECK_FOLDER_DIS_THREASHOLD) {
                        target = holder;
                        break;
                    }
                }
            }
            canMove = target == null;
            if (dragListener != null) {
                dragListener.onChooseNearBy(target);
            }
        } else {
            canMove = true;
        }
        return super.chooseDropTarget(source, dropTargets, curX, curY);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder source, RecyclerView.ViewHolder target) {
        return canMove && mAdapter.canMove();
    }

    /**
     * 当onMove return true的时候调用(一般不用我们自己处理，直接super就好)
     */
    public void onMoved(final RecyclerView recyclerView,
                        final RecyclerView.ViewHolder viewHolder,
                        int fromPos,
                        final RecyclerView.ViewHolder target,
                        int toPos,
                        int x,
                        int y) {
        super.onMoved(recyclerView, viewHolder, fromPos, target, toPos, x, y);
    }

    /**
     * 针对swipe和drag状态，当一个item view在swipe、drag状态结束的时候调用
     * drag状态：当手指释放的时候会调用
     * swipe状态：当item从RecyclerView中删除的时候调用，一般我们会在onSwiped()函数里面删除掉指定的item view
     */
    public void clearView(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        super.clearView(recyclerView, viewHolder);
    }


    /**
     * 针对swipe和drag状态，整个过程中一直会调用这个函数,随手指移动的view就是在super里面做到的(和ItemDecoration里面的onDraw()函数对应)
     */
    public void onChildDraw(Canvas c,
                            RecyclerView recyclerView,
                            RecyclerView.ViewHolder viewHolder,
                            float dX,
                            float dY,
                            int actionState,
                            boolean isCurrentlyActive) {
        super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }


    /**
     * 针对swipe和drag状态，整个过程中一直会调用这个函数(和ItemDecoration里面的onDrawOver()函数对应)
     * 这个函数提供给我们可以在RecyclerView的上面再绘制一层东西，比如绘制一层蒙层啥的
     */
    public void onChildDrawOver(Canvas c,
                                RecyclerView recyclerView,
                                RecyclerView.ViewHolder viewHolder,
                                float dX,
                                float dY,
                                int actionState,
                                boolean isCurrentlyActive) {
        super.onChildDrawOver(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
    }


}
